import qt
import sys
from qt import *
import threading
import subprocess
import os
import message_box_with_details
class MessageBoxWithLog(message_box_with_details.MessageBoxWithDetails):
    def __init__(
        self,
        parent,
        caption,
        message,
        details,
        *args
        ):
        apply(message_box_with_details.MessageBoxWithDetails.__init__, (self, parent) + args)
        self.setCaption(caption)
        self.messageLabel.setText(message)
        self.detailsView.hide()
        self.detailsView.append(details)
        self.connect(
            self.showDetailsButton,
            qt.SIGNAL("clicked()"),
            self.toggleDetails
            )
        self.connect(
            self.buttonOk,
            qt.SIGNAL("clicked()"),
            self,
            qt.SLOT("accept()")
            )
    def slotUpdateMessage(self, newMessage):
        self.messageLabel.setText(newMessage)
    def slotAppendDetails(self, details):
        self.detailsView.append(details)
    def toggleDetails(self):
        if self.detailsView.isHidden():
            self.detailsView.show()
        else:
            self.detailsView.hide()

def messageBoxWithLog(
    parent,
    caption,
    message,
    details
    ):
    messageBox = MessageBoxWithLog(
        parent,
        caption,
        message,
        details
        )
    messageBox.show()
    return messageBox.exec_loop()

class FrontendCustomEvent(qt.QCustomEvent):
    def __init__(self, data, *args):
        apply(qt.QCustomEvent.__init__, (self,) + args)
        self.pythonData = data

class WizardUiFrontend(qt.QObject):
    class TerminationRequested(Exception):
        def __init__(self, *args):
            apply(Exception.__init__, (self,) + args)
    def __init__(self, *args):
        apply(qt.QObject.__init__, (self,) + args)
        self.eventNum = qt.QEvent.User + 777
        self.pageOutput = None
        self.inputWaitCondition = threading.Condition()
        self.terminateRequestedFlag = False
        self.forceTerminationRequestedFlag = False
        self.backendTerminatedFlag = False
    def sendEvent(self, data):
        import qt
        event = FrontendCustomEvent(data, self.eventNum)
        qt.QApplication.postEvent(self, event)
    def customEvent(self, event):
        if event.type() == self.eventNum:
            eventSubtype, arg1, arg2 = event.pythonData
            if eventSubtype == "signal":
                print "Emitting signal %s, params=%s" % (repr(arg1), repr(arg2))
                self.emit(arg1, (arg2,))
            else:
                print "Received unknown subtype, subtype=%s, data=" % (eventSubtype, repr(event.data()))
        else:
            print "Unknown event received"
    def performAction(self, actionName, actionOptions):
        self.sendEvent(["signal", PYSIGNAL(actionName), actionOptions])
    def slotGetPageOutput(self, pageOutput):
        print "slotGetPageOutput, pageOutput=%s" % repr(pageOutput)
        self.inputWaitCondition.acquire()
        try:
            if self.pageOutput == None:
                self.pageOutput = pageOutput
            else:
                print "Trying to set page output second time, pageOutput=%s" % repr(pageOutput)
            self.inputWaitCondition.notify()
        finally:
            self.inputWaitCondition.release()
    def requestBackendTermination(self, force = False):
        print "Frontend requested backend termination"
        self.inputWaitCondition.acquire()
        try:
            self.terminateRequestedFlag = True
            if self.forceTerminationRequestedFlag == False:
                self.forceTerminationRequestedFlag = force
            self.inputWaitCondition.notify()
        finally:
            self.inputWaitCondition.release()
    def terminateRequested(self):
        self.inputWaitCondition.acquire()
        try:
            flag = self.terminateRequestedFlag
        finally:
            self.inputWaitCondition.release()
        return flag
    def raiseIfTerminateRequested(self):
        if self.terminateRequested():
            raise self.TerminationRequested, "Frontend requested termination of backend"
    def raiseIfForceTerminateRequested(self):
        if self.forceTerminateRequested():
            self.raiseIfTerminateRequested()

    def forceTerminateRequested(self):
        self.inputWaitCondition.acquire()
        try:
            flag = self.forceTerminationRequestedFlag
        finally:
            self.inputWaitCondition.release()
        return flag
    def isBackendTerminated(self):
        self.inputWaitCondition.acquire()
        try:
            flag = self.backendTerminatedFlag
        finally:
            self.inputWaitCondition.release()
        return flag
    def backendTerminated(self):
        print "Backend informed about termination"
        self.inputWaitCondition.acquire()
        try:
            self.backendTerminatedFlag = True
        finally:
            self.inputWaitCondition.release()
    def waitForInput(self, nonBlocking = False):
        print "Waiting for input"
        self.inputWaitCondition.acquire()
        try:
            if self.pageOutput == None:
                if nonBlocking == True:
                    print "No output and nonblocking wait was requested"
                    return None
                print "Sleeping for page output"
                self.inputWaitCondition.wait()
            if self.terminateRequestedFlag == True:
                print "Requested termination of backend"
                raise self.TerminationRequested, "Frontend requested termination of backend"
            pageOutput = self.pageOutput
            self.pageOutput = None
        finally:
            self.inputWaitCondition.release()
        print "Returning page output=%s" % pageOutput
        return pageOutput

